﻿using Autofac.Extensions.DependencyInjection;
using FrameWorkCore;
using ShardingCore.Sharding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Repository.FrameWorkCore
{
    public interface IUnitOfWorkManager
    {
        public Task SaveActiveUnitOfWorkAsync();

        public void SaveActiveUnitOfWork();

        public IDisposable DisableFilter(bool IsDisable);
    }

    public class UnitOfWorkManager : IUnitOfWorkManager
    {
        private readonly IEnumerable<AbstractShardingDbContext> dbContexts;
        private readonly IServiceProvider serviceProvider;
        private readonly IUnitOfWork unitOfWork;


        public UnitOfWorkManager(IServiceProvider _serviceProvider, IUnitOfWork _unitOfWork)
        {
            serviceProvider = _serviceProvider;
            dbContexts = ((AutofacServiceProvider)_serviceProvider).LifetimeScope.ComponentRegistry.Registrations
            .Where(x => typeof(AbstractShardingDbContext).IsAssignableFrom(x.Activator.LimitType))
            .Select(x => (AbstractShardingDbContext)serviceProvider.GetService(x.Activator.LimitType));
            unitOfWork = _unitOfWork;
        }

        public IDisposable DisableFilter(bool IsDisable = false)
            => unitOfWork.IgnoreQueryFilters(IsDisable);


        public void SaveActiveUnitOfWork()
        {
            foreach (var dbContext in dbContexts)
            {
                if (dbContext.Database.CurrentTransaction != null)
                    dbContext.SaveChanges();
            }
        }
                       

        public async Task SaveActiveUnitOfWorkAsync()
        {
            foreach (var dbContext in dbContexts)
            {
                if (dbContext.Database.CurrentTransaction != null)
                   await dbContext.SaveChangesAsync();
            }
        }
    }
}
